import { existsSync, writeFileSync } from 'fs';
import { join } from "path";
import { ITableOutput, IWriter, IFileMerge } from "../../inters/InterfaceApi";
import { convertMgr } from "../mgr/ConvertMgr";
import { mkdirsSync } from '../../utils/CpFile';
import { logout } from '../../utils/LogUtil';

export class JsonMergeBranchWriter implements IWriter {

    private _cfg: ITableOutput;
    protected _platFile: any;
    // protected _path: string;

    write(data: any, options?: any, callback?: (res?: any) => void) {

        // this._path = options.path;
        this._cfg = data;
        if (!this._cfg.merge) {
            logout('当前没有合并的配置')
            return;
        }
        let convert = convertMgr.crtConvert;
        let tableData = convert.tableData;

        this._platFile = {};
        // todo 这里只实现了合并第一组文件，默认是所有都合并的
        let mergeData = this._cfg.merge[0];

        this._platFile['def'] = {};
        // 首先写入默认的一组数据
        for (let table in tableData) {
            // 这里先简单判断，使用 _ 来分割key来判断plat
            let temp = table.split("_");
            if (temp.length > 1) {
                continue;
            }
            let td = tableData[table];
            if(td.data==null)continue;
            // 先将所有的json都导出
            let str = JSON.stringify(td.data);

            this._platFile['def'][table] = Buffer.from(str);
        }

        for (let i = 0; i < convert.plats.length; i++) {
            let platName = convert.plats[i];
            this._platFile[platName] = {};
            // 首先写入默认的一组数据
            for (let table in tableData) {
                // 这里先简单判断，使用 _ 来分割key来判断plat
                let temp = table.split("_");
                if (temp.length > 1) {
                    continue;
                }
                let td = tableData[table];
                // 先将所有的json都导出
                let str = JSON.stringify(td.data);
                this._platFile[platName][table] = Buffer.from(str);
            }
            for (let table in tableData) {
                // 这里先简单判断，使用 _ 来分割key来判断plat
                let temp = table.split("_");
                if (temp.length > 1 && temp[temp.length - 1] == platName) {
                    let td = tableData[table];
                    // 先将所有的json都导出
                    let str = JSON.stringify(td.data);
                    this._platFile[platName][td.tableName] = Buffer.from(str);
                }

            }
        }

        for (let key in this._platFile) {
            let platObj = this._platFile[key];
            this._saveFile(platObj, mergeData, key);
        }

    }

    protected _saveFile(fileContent: any, mergeData: IFileMerge, platName: string = 'def', lang: string = 'cn') {
        let headObj = {};
        let index = 0;
        for (let key in fileContent) {
            // if (key.substr(key.length - 5) != '.json') {
            //     continue;
            // }
            let content: Buffer = fileContent[key];
            if (content.length <= 0) {
                continue;
            }
            headObj[key] = [index, content.length];
            index += content.length + 1;
        }
        var headBuff = Buffer.from(JSON.stringify(headObj));
        var contentBuff = Buffer.alloc(4 + headBuff.length + index - 1);
        contentBuff.writeUInt32LE(headBuff.length, 0);
        contentBuff.fill(headBuff, 4);

        for (var key in headObj) {
            var [start, len] = headObj[key];
            contentBuff.fill(fileContent[key], start + 4 + headBuff.length);
        }

        let dir = mergeData.path;//join(this._path, mergeData.path);
        if (!existsSync(dir)) {
            mkdirsSync(dir);
        }
        let platAndLang = '';
        if (platName != "def") {
            platAndLang += ("_" + platName);
        }
        if (lang != 'cn') {
            platAndLang += ("_" + lang);
        }
        let fileName = `${mergeData.name}${platAndLang}${mergeData.nameExt}`;

        if (mergeData.compress == 1) {
            let zlib = require("zlib");
            let result = zlib.deflateRawSync(contentBuff);
            writeFileSync(join(dir, fileName), result);
        } else if (mergeData.compress == 0) {
            writeFileSync(join(dir, fileName), contentBuff);
        }
    }
}